//
//  Server.swift
//  SerViceTest
//
//  Created by 薛永伟 on 2019/5/14.
//  Copyright © 2019 Yuri. All rights reserved.
//

import Foundation
import Alamofire
import SwiftyJSON

/// 服务器
class YRAPI:NSObject {
    
    /// 域名(项目中难免遇到多域名接口，从domain开始进行区分)
    enum Domain {
        
        /// 默认使用的域名
        case Default
        
        /// 资源（文件CDN等）
        case Resource
        
        /// 域名
        var host:String {
            
            switch self {
            case .Default:
                switch Environment.current {
                case .develop:
                    return "192.168.119.119"
                case .gray:
                    return "demo.com"
                case .release:
                    return "demo.com"
                }
            default:
                return ""
            }
        }
        
    }
    
    /// Base_URl
    static func Base_URL(_ domain:Domain = Domain.Default ) -> String {
        
        return "\(domain.scheme)://\(domain.host)"
        
    }
    
    /// 全局通用的header，比如加入cookie和用户信息token什么的
    fileprivate static func globalHeader() -> HTTPHeaders {
        
        let headers:HTTPHeaders = ["token":""]
        return headers
    }
    
}

//MARK: - --------------Domain--------------

extension YRAPI.Domain {
    
    /// 协议（一般测试环境使用http）
    var scheme:String {
        
        if YRAPI.Environment.current == .develop {
            return "http"
        }
        return "https"
    }
    
    
    /// 通用的header
    var commonHeader:HTTPHeaders? {
        
        switch self {
        case .Default:
            // 这里用了通用了header
            var header = YRAPI.globalHeader()
            header["demo"] = "YR"
            return header
        default:
            return nil
        }
    }
}

//MARK: - --------------Reachability--------------
extension YRAPI {
    
    /// 数据可达
    struct Reachability {
        
        
        private static var manager = NetworkReachabilityManager.init()
        
        /// 开始监听网络状态
        static func startListening(){
            
            manager?.startListening()
        }
        
        /// 是否可达
        static var isReachable:Bool {
            
            let result = manager?.isReachable ?? false
            return result
        }
        
        /// 信任所有证书信任询问
        static func trustAllChallenge(){
            
            SessionManager.default.delegate.sessionDidReceiveChallenge = { session,challenge in
                
                return (URLSession.AuthChallengeDisposition.useCredential,
                        URLCredential(trust:challenge.protectionSpace.serverTrust!))
            }
        }
    }
    
}


//MARK: - --------------Environment--------------
extension YRAPI {
    
    /// 运行环境
    enum Environment:Int{
        
        /// 开发环境
        case develop    =   -1
        
        /// 灰度环境
        case gray       =   1
        
        /// //生产环境
        case release    =   0
        
        /// 当前的运行环境
        static var current:Environment {
            
            let stateInt = Preference.Develop.APIEnvironment.int
            //默认release环境，保底显示线上数据
            let evironment = Environment.init(rawValue: stateInt) ?? .release
            return evironment
        }
    }
    
    /// 协议 (一般开发环境会用http，而生产环境用https)
    static var urlProtocol: String = {
        
        if Environment.current == .develop {
            return "http"
        }
        return "https"
    }()
    
}


//MARK: - --------------APIUrlable--------------

protocol APIUrlable:NSObjectProtocol {
    
    /// 协议的规定url方法，正确拼接出当前模块的url路径
    static func Base_URL() -> String
}

extension APIUrlable {
    
    /// 创建给定路径的url，path需包含前缀"/xx"
    static func urlWithPath(_ path:String) -> URL {
        
        let urlstr = Base_URL() + path
        
        if let url = URL.init(string: urlstr) {
            
            return url
        }else{
            assertionFailure("不能创建URL:\(urlstr)!")
            return URL.init(string: urlstr)!
        }
    }
}



//MARK: - --------------cookie--------------
extension YRAPI {
    
    /// cookie相关
    struct Cookie {
        
        /// 把server返回的cookie更新到本地
        static func updateCookies(response: DataResponse<Any>){
            
            let headerFields = response.response?.allHeaderFields as! [String: String]
            let url = response.request?.url
            
            let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url!)
            
            var cookieArray = [ [HTTPCookiePropertyKey : Any ] ]()
            for cookie in cookies {
                cookieArray.append(cookie.properties!)
            }
            
            UserDefaults.standard.set(cookieArray, forKey: "server_tokens")
        }
        
        /// 恢复保存的cookies，理论上不需要自行处理
        static func restoreCookies(){
            
            if let cookieArray = UserDefaults.standard.array(forKey: "server_tokens") {
                for cookieData in cookieArray {
                    if let dict = cookieData as? [HTTPCookiePropertyKey : Any] {
                        if let cookie = HTTPCookie.init(properties : dict) {
                            HTTPCookieStorage.shared.setCookie(cookie)
                        }
                    }
                }
            }
        }
        
        /// t恢复token到cookie中
        static func restoreTokenCooike(){
            
            if let token = Preference.User.TokenAuth.string {
                addTokenCookie(token: token, in: nil)
            }else{
                YRLog("没有能恢复的token", type: .warning)
            }
        }
        
        /// 把token添加到cookie里
        static func addTokenCookie(token:String,
                                   in url:URL?){
            
            var cookieProperties = [HTTPCookiePropertyKey: String]()
            cookieProperties[HTTPCookiePropertyKey.name] = "x-auth-token"
            cookieProperties[HTTPCookiePropertyKey.value] = token
            cookieProperties[HTTPCookiePropertyKey.domain] = url?.host ?? YRAPI.Domain.Default.host
            cookieProperties[HTTPCookiePropertyKey.path] = "/"
            if let tokenCookie = HTTPCookie(properties: cookieProperties){
                HTTPCookieStorage.shared.setCookie(tokenCookie)
                Preference.User.TokenAuth.setValue(any: token)
            }else{
                YRLog("无法创建token的scookie:\(token)", type: .error)
            }
        }
        
        
        /// 清理token
        static func clearToken(){
            
            if let cookies = HTTPCookieStorage.shared.cookies?.enumerated(){
                for (_,cookie) in  cookies{
                    if cookie.domain == YRAPI.Domain.Default.host {
                        HTTPCookieStorage.shared.deleteCookie(cookie)
                    }
                }
            }
        }
    }
}

